﻿using System;
using System.Collections.Generic;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Ordinaire.Social.Data
{
    /// <summary>
    /// Class representation of table 'Organisationss'.
    /// </summary>
    [Table]
    public class Organisations : Data<int, string>
    {
        #region Variables

        /// <summary>
        /// Provider name of the data source.
        /// </summary>
        private string providerName;

        /// <summary>
        /// Provider assembly name.
        /// </summary>
        private string providerAssemblyName;

        /// <summary>
        /// The id of the default address in table "Addresses".
        /// </summary>
        private int defaultAddressesId;

        #endregion

        #region Property methods

        /// <summary>
        /// Get or set the entry unique identifier.
        /// </summary>
        [Column(IsPrimaryKey = true, IsDbGenerated = true, UpdateCheck = UpdateCheck.Never)]
        public override int Id
        {
            get { return base.Id; }
            set { base.Id = value; }
        }

        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        [Column(DbType = "nvarchar(50) NOT NULL", UpdateCheck = UpdateCheck.Never)]
        public override string Name
        {
            get { return base.Name; }
            set { base.Name = value; }
        }

        /// <summary>
        /// Gets or sets the id of the default address in table "Addresses".
        /// </summary>
        [Column(UpdateCheck = UpdateCheck.Never)]
        public int DefaultAddressesId
        {
            get { return this.defaultAddressesId; }
            set { this.defaultAddressesId = value; }
        }

        /// <summary>
        /// Gets or sets the provider name of the data source.
        /// </summary>
        [Column(CanBeNull = false, DbType = "nvarchar(100) NOT NULL", UpdateCheck = UpdateCheck.Never)]
        public string ProviderName
        {
            get { return this.providerName; }
            set { this.providerName = value; }
        }

        /// <summary>
        /// Gets or sets the provider assembly name.
        /// </summary>
        [Column(DbType = "nvarchar(max) NOT NULL", UpdateCheck = UpdateCheck.Never)]
        public string ProviderAssemblyName
        {
            get { return this.providerAssemblyName; }
            set { this.providerAssemblyName = value; }
        }

        /// <summary>
        /// Get or set the username who created this entry.
        /// </summary>
        [Column(DbType = "nvarchar(10) NOT NULL", UpdateCheck = UpdateCheck.Never)]
        public override string CreatedBy
        {
            get { return base.CreatedBy; }
            set { base.CreatedBy = value; }
        }

        /// <summary>
        /// Get or set the date when the entry was first created.
        /// </summary>
        [Column(DbType = "datetime", UpdateCheck = UpdateCheck.Never)]
        public override DateTime? CreateDate
        {
            get { return base.CreateDate; }
            set { base.CreateDate = value; }
        }

        /// <summary>
        /// Get or set the username who last updated this entry.
        /// </summary>
        [Column(DbType = "nvarchar(10)", UpdateCheck = UpdateCheck.Never)]
        public override string UpdatedBy
        {
            get { return base.UpdatedBy; }
            set { base.UpdatedBy = value; }
        }

        /// <summary>
        /// Get or set the date when the entry was last updated.
        /// </summary>
        [Column(DbType = "datetime", UpdateCheck = UpdateCheck.Never)]
        public override DateTime? UpdateDate
        {
            get { return base.UpdateDate; }
            set { base.UpdateDate = value; }
        }

        #endregion

        #region Expressions

        /// <summary>
        /// Returns a related expression to find data from data source that has the specified id.
        /// </summary>
        /// <param name="id">the id of data to look for</param>
        /// <returns>related expression</returns>
        public static Expression<Func<Organisations, bool>> IdIs(int id)
        {
            return d => d.Id.Equals(id);
        }

        /// <summary>
        /// Returns a related expression to find data in table "Organisations" that matches with the specified name.
        /// </summary>
        /// <param name="name">the organisation name</param>
        /// <param name="providerName">the provider name</param>
        /// <returns>related expression</returns>
        public static Expression<Func<Organisations, bool>> NameIs(string name, string providerName = null)
        {
            name = name.TrimExtraSpaces().ToLower();

            if (String.IsNullOrEmpty(providerName))
            {
                return d => d.Name.ToLower() == name;
            }
            else
            {
                providerName = providerName.ToLower();
                return d => d.Name.ToLower() == name && d.ProviderName.ToLower() == providerName;
            }
        }

        #endregion
    }

    /// <summary>
    /// Contains list of available extension methods associated with Ordinaire.Social.Data.Organisations.
    /// </summary>
    public static class OrganisationsExtension
    {
        /// <summary>
        /// Converts organisation's data to a new instance of Ordinaire.Social.Organisation.
        /// </summary>
        /// <param name="data">data to be converted</param>
        /// <returns>new instance of Ordinaire.Social.Organisation</returns>
        public static Organisation ToOrganisation(this Organisations data)
        {
            if (data == null)
            {
                return null;
            }

            Organisation instance     = (Organisation) data.ProviderName.Instance(data.ProviderAssemblyName);
            instance.Id               = data.Id;
            instance.Name             = data.Name;
            instance.DefaultAddressId = data.DefaultAddressesId;

            return instance;
        }

        /// <summary>
        /// Converts organisation's data to a new instance of Ordinaire.Social.Organisation.
        /// </summary>
        /// <typeparam name="TOrganisation">derived type of Ordinaire.Social.Organisation</typeparam>
        /// <param name="data">data to be converted</param>
        /// <returns>new instance of specified type</returns>
        public static TOrganisation ToOrganisation<TOrganisation>(this Organisations data)
            where TOrganisation : Organisation
        {
            if (data == null)
            {
                return null;
            }

            TOrganisation instance    = typeof(TOrganisation).Instance<TOrganisation>();
            instance.Id               = data.Id;
            instance.Name             = data.Name;
            instance.DefaultAddressId = data.DefaultAddressesId;
            return instance;
        }
    }
}
